c程式變成可執行文件(.o檔)大致上為以下步驟:
c語言 -----> 預處理文件 -----> 彙編語言 -----> 可重定位文件 ------> 可執行文件
* 預處理文件(gcc -E) :展開巨集,將library(#include<.h>)和宏定義(#define)載入並展開
* 彙編語言(gcc -S): 即組合語言,由編譯器(compiler)生成,一般而言,生成過成為 1. 語法表示 2. 語法分析 3. 中間碼生成 4. 代碼生成 5. 代碼優化
* 可重定位文件(gcc -C):二進制文件,但此時上不能執行,因為還沒有將所需的object files 連接起來
* 可執行文件(ld):由連接器將所有object files連接起來,形成可執行elf file(在linux系統下為elf,windows是pe file,兩者接源自於coff file)
以下,我們要提幾個點
1.在這裡,有沒有一個疑惑,可重定位文件跟可執行文件兩者都是二進制檔,為什麼要分開做,不能一次做完嗎?
這裡分開生成的目的是什麼呢?
其目的就是:分配位置! 在還沒指定真正的位置時,假如你呼叫一個printf函式,它存於另一個object file,此時,在二進制程式碼的部份,它地址顯示為0。
2.我們想要分析object file時,大多使用readelf或objdump等工具
$ cat test.c
int main(){
printf("hello\n");
}
$ gcc -C test.c -o test.o
$ readelf -h test.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1060
Start of program headers: 64 (bytes into file)
Start of section headers: 14712 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
第一行的magic number(7f 45 4c..)是告訴電腦這個檔案是elf檔
必須注意的是program header和section header!
明天再把elf裡面結構說更清楚些,然後來大致說明一下內部relocation的機制!